package swind.web.service.imp;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import swind.common.ExamTest.TestUtils;
import swind.web.dao.IScoreDao;
import swind.web.dao.ISubjectDao;
import swind.web.dao.ITestDao;
import swind.web.dao.ITestTypeDao;
import swind.web.dao.IUserDao;
import swind.web.entities.ExamScore;
import swind.web.entities.ExamSubject;
import swind.web.entities.ExamTest;
import swind.web.entities.ExamTestType;
import swind.web.entities.ExamUser;
import swind.web.service.IStudentService;
import swind.web.service.IVoMachine;
import swind.web.vo.ScoreVo;
import swind.web.vo.SubjectVo;
import swind.web.vo.TestSubjectVo;
import swind.web.vo.TestTypeVo;
import swind.web.vo.TestVo;

@Transactional
@Service("studentServiceImp")
public class StudentServiceImp implements IStudentService {
	@Resource(name="subjectDaoImp")
	ISubjectDao subjectDaoImp;
	
	@Resource(name="scoreDaoImp")
	IScoreDao scoreDaoImp;
	
	@Resource(name="userDaoImp")
	IUserDao userDaoImp;
	
	@Resource(name="voMachine")
	IVoMachine voMachine;
	
	@Resource(name="testDaoImp")
	ITestDao testDaoImp;
	
	@Resource(name="testTypeDaoImp")
	ITestTypeDao testTypeDaoImp;
	
	@Override
	public List<ExamSubject> getSubjectByExamUser(ExamUser eu){
		//List<ExamSubject> list=subjectDaoImp.loadAll();
		List<ExamSubject> list=new ArrayList<ExamSubject>(eu.getExamSubjects());
		return list;
	}
	
	@Override
	public List<ExamScore> getScoreByExamUser(ExamUser eu){
		List<ExamScore> list=scoreDaoImp.find("from ExamScore esc where esc.userId = '"+eu.getUserId()+"'");
		return list;
	}
	
	@Override
	public List<SubjectVo> dealSubjectScoreByExamUser(ExamUser eu,List<ExamSubject> sublist,List<ExamScore> scolist){
		List<SubjectVo> list=new ArrayList<SubjectVo>();
		OK:
		for(ExamSubject es:sublist){
			for(ExamScore esc:scolist){
				if(es.getSubId()==esc.getSubjectId()){
					SubjectVo sev=voMachine.EntityToVo(es, esc);
					sev.setHasExam(true);
					list.add(sev);
					continue OK;
				}
			}
			list.add(voMachine.EntityToVo(es, null));
		}
		
		 
		return list;
	}
	
	@Override
	public ScoreVo getScoreById(int id){
		return voMachine.EntityToVo(scoreDaoImp.get(id));
	}
	
	
	@Override
	public ExamUser getExamUserById(String id){
		return userDaoImp.get(id);
	}
	
	@SuppressWarnings("unused")
	@Override
	public List<TestVo> getTestBySubject(Integer subId){
		ExamSubject subject = subjectDaoImp.get(subId);
		int totalTestCount = subject.getTestCount();
		int totalTestScore = (int) subject.getTotalScore();
		
		//1 校验科目总分和总题数是否匹配
		Map<Integer,Integer> testTypeScoreMap = new HashMap<Integer,Integer>();
		List<ExamTestType> examTestTypeList = testTypeDaoImp.loadAll();
		for(ExamTestType examTestType:examTestTypeList){
			testTypeScoreMap.put(examTestType.getId(), examTestType.getScore());
		}
		if(!TestUtils.checkSubjectScoreAndCount(totalTestCount, totalTestScore, testTypeScoreMap)){
			return null;
		}
		
		//2 获取各个题型的数目
		Map<Integer,Integer> testCountMap = TestUtils.getTestConutByScore(totalTestCount, testTypeScoreMap);
		
		//3 根据科目获取各个题型所有题目
		Map<Integer,List<TestVo>> totalTestMap = new HashMap<Integer,List<TestVo>>();
		for(ExamTestType examTestType:examTestTypeList){
			List<ExamTest> testList = testDaoImp.getTotalTestMapBySubject(subId,examTestType.getId());
			List<TestVo> testVoList = new ArrayList<TestVo>();
			for(ExamTest examTest : testList){
				TestVo testVo = new TestVo();
				BeanUtils.copyProperties(examTest, testVo);
				testVoList.add(testVo);
			}
			totalTestMap.put(examTestType.getId(), testVoList);
		}
		
		//4 生成随机题目
		Map<Integer,List<TestVo>> resultTestMap = new HashMap<Integer,List<TestVo>>();
		for(Integer key: testCountMap.keySet()){
			int oneTotalCount = testCountMap.get(key);
			List<TestVo> oneTotalTest = totalTestMap.get(key);
			List<Integer> resultTestIdList = TestUtils.getRandomList(oneTotalCount,oneTotalTest);			
			
			List<ExamTest> resultExamTestList = testDaoImp.getTestByIdList(resultTestIdList);
			if(resultExamTestList==null){
				return null;
			}
			List<TestVo> resultTestList = new ArrayList<TestVo>();
			for(ExamTest examTest:resultExamTestList){
				TestVo testVo =new TestVo();
				TestTypeVo testTypeVo = new TestTypeVo();
				TestSubjectVo testSubjectVo =new TestSubjectVo();
				BeanUtils.copyProperties(examTest, testVo);
				BeanUtils.copyProperties(examTest.getTestType(),testTypeVo);
				BeanUtils.copyProperties(examTest.getSubject(), testSubjectVo);
				testVo.setSubjectVo(testSubjectVo);
				testVo.setTestTypeVo(testTypeVo);
				testVo.setAnswer(null);
				resultTestList.add(testVo);
			}
			
			resultTestMap.put(key, resultTestList);
		}
		
		List<TestVo> resultTotalList = new ArrayList<TestVo>();
		for(Integer key:resultTestMap.keySet()){
			resultTotalList.addAll(resultTestMap.get(key));
		}
		return resultTotalList;
	}

	@Override
	public int countTestScore(String[] idArr, String[] answerArr) {
		int score = 0;
		Map<Integer,String> testAnswerMap = new HashMap<Integer,String>();
		for(int i = 0;i<idArr.length;i++){
			testAnswerMap.put(Integer.valueOf(idArr[i]), answerArr[i]);
		}
		List<Integer> resultTestIdList = new ArrayList<Integer>(testAnswerMap.keySet());
		List<ExamTest> examTests = testDaoImp.getTestByIdList(resultTestIdList);
		for(ExamTest examTest :examTests){
			String answerT = testAnswerMap.get(examTest.getId());
			if(answerT.equals(examTest.getAnswer())){
				score = score + examTest.getTestType().getScore();
			}
		}
		return score;
	}

	@Override
	public boolean setNewScore(int totalSocre, int subId, String studentId) {
		ExamScore examScore = new ExamScore();
		examScore.setExamTime(new Date());
		examScore.setScore(totalSocre);
		examScore.setSubjectId(subId);
		examScore.setUserId(studentId);
		scoreDaoImp.save(examScore);
		
		return true;
	}
	
	@Override
	public boolean hasScore(int subId,String userId){
		ExamScore score= scoreDaoImp.getScore(subId,userId);
		if(score==null){
			return false;
		}
		
		return true;
	}
	
	@Override
	public int getExamTime(int subId){
		return subjectDaoImp.get(subId).getTotalTime();
	}

}
